package glossos.parsing;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

public class WordBuffer extends Observable{

	private StringBuilder mainBuilder, candidatesBuilder;
	private List<String> wordList;
	
	public WordBuffer(Observer observer) {
		this();
		addObserver(observer);
	}
	
	public WordBuffer() {
		mainBuilder = new StringBuilder();
		candidatesBuilder = new StringBuilder();
		wordList = new ArrayList<String>();
	}
	
	/**
	 * Appends a new character to this buffer.
	 * @param c any character.
	 */
	public void append(char c) {
		if (candidatesBuilder.length() > 0){
			mainBuilder.append(candidatesBuilder);
			candidatesBuilder = new StringBuilder();
		}
		mainBuilder.append(c);
	}
	
	public void appendCandidate(char c){
		candidatesBuilder.append(c);
	}

	/**
	 * Closes this buffer and notifies all observers that there is nothing more to process.
	 */
	public void close() {
        group();
        flush();
        setChanged();
		notifyObservers();
	}

	/**
	 * Groups the previously appended characters, forming a new word.
	 */
	public void group() {
		if (mainBuilder.length() > 0){
			wordList.add(mainBuilder.toString());
			mainBuilder = new StringBuilder();
		}
	}
		
	public void releaseCandidates(){
		candidatesBuilder = new StringBuilder();
	}
	
	/**
	 * Flushes this buffer, notifying all observers that a new word list is ready to be processed.
	 */
	public void flush() {
        if (!wordList.isEmpty()){
            setChanged();
            notifyObservers(Collections.unmodifiableList(wordList));
            wordList = new ArrayList<String>();
        }
    }

	@Override
	public String toString() {
		return mainBuilder.toString();
	}
}
